# -*- coding: utf-8 -*-
# from odoo import api, fields, models,_
from odoo.addons import decimal_precision as dp
from odoo.exceptions import AccessError, UserError, ValidationError
from passlib.context import CryptContext
import os
import hashlib
import json
import logging
import odoo
from odoo import api, http, models,fields,_
from odoo.http import request
from odoo.tools import file_open, image_process, ustr
from odoo.tools.misc import str2bool
import re

WORKTYPE_SELECTION=[('A1M0','单扭矩模式'),('A1M','多扭矩模式'),('A2M0','单扭矩+角度模式'),('A2M','多扭矩+角度模式')]
#继承这个类，增加env_company
class Http(models.AbstractModel):
    _inherit = 'ir.http'
    def session_info(self):
        user = self.env.user
        session_uid = request.session.uid
        version_info = odoo.service.common.exp_version()

        if session_uid:
            user_context = dict(self.env['res.users'].context_get())
            if user_context != request.session.context:
                request.session.context = user_context
        else:
            user_context = {}

        IrConfigSudo = self.env['ir.config_parameter'].sudo()
        max_file_upload_size = int(IrConfigSudo.get_param(
            'web.max_file_upload_size',
            default=128 * 1024 * 1024,  # 128MiB
        ))
        mods = odoo.conf.server_wide_modules or []
        if request.db:
            mods = list(request.registry._init_modules) + mods
        session_info = {
            # "proto_id":user.proto_id.id, #dbh 增加的与扳手通讯的协议
            "env_company":user.company_id.name,#dbh 增加的当前登录用户的公司名 
            "uid": session_uid,
            "is_system": user._is_system() if session_uid else False,
            "is_admin": user._is_admin() if session_uid else False,
            "user_context": user_context,
            "db": self.env.cr.dbname,
            "server_version": version_info.get('server_version'),
            "server_version_info": version_info.get('server_version_info'),
            "support_url": "https://www.odoo.com/buy",
            "name": user.name,
            "username": user.login,
            "partner_display_name": user.partner_id.display_name,
            "company_id": user.company_id.id if session_uid else None,  # YTI TODO: Remove this from the user context
            "partner_id": user.partner_id.id if session_uid and user.partner_id else None,
            "web.base.url": IrConfigSudo.get_param('web.base.url', default=''),
            "active_ids_limit": int(IrConfigSudo.get_param('web.active_ids_limit', default='20000')),
            'profile_session': request.session.profile_session,
            'profile_collectors': request.session.profile_collectors,
            'profile_params': request.session.profile_params,
            "max_file_upload_size": max_file_upload_size,
            "home_action_id": user.action_id.id,
            "cache_hashes": {
                "translations": self.env['ir.http'].sudo().get_web_translations_hash(
                    mods, request.session.context['lang']
                ) if session_uid else None,
            },
            "currencies": self.sudo().get_currencies(),
            'bundle_params': {
                'lang': request.session.context['lang'],
            },
        }
        if request.session.debug:
            session_info['bundle_params']['debug'] = request.session.debug
        if self.env.user.has_group('base.group_user'):
            # the following is only useful in the context of a webclient bootstrapping
            # but is still included in some other calls (e.g. '/web/session/authenticate')
            # to avoid access errors and unnecessary information, it is only included for users
            # with access to the backend ('internal'-type users)
            menus = self.env['ir.ui.menu'].load_menus(request.session.debug)
            ordered_menus = {str(k): v for k, v in menus.items()}
            menu_json_utf8 = json.dumps(ordered_menus, default=ustr, sort_keys=True).encode()
            session_info['cache_hashes'].update({
                "load_menus": hashlib.sha512(menu_json_utf8).hexdigest()[:64], # sha512/256
            })
            session_info.update({
                # current_company should be default_company
                "user_companies": {
                    'current_company': user.company_id.id,
                    'allowed_companies': {
                        comp.id: {
                            'id': comp.id,
                            'name': comp.name,
                            'sequence': comp.sequence,
                        } for comp in user.company_ids
                    },
                },
                "show_effect": True,
                "display_switch_company_menu": user.has_group('base.group_multi_company') and len(user.company_ids) > 1,
            })
        return session_info
# class Proto(models.Model):
#     _name = "dtw.proto"
#     name = fields.Char("通讯协议名称")
#     proto_from = fields.Char("使用的扳手厂家")

# class Company(models.Model):
#     _inherit = "res.company"
#     proto_id = fields.Many2one("dtw.proto",string="使用的通讯协议")
    
# class Users(models.Model):
#     _inherit = "res.users"
#     proto_id = fields.Many2one(comodel_name="dtw.proto",related="company_id.proto_id",string="使用的通讯协议",store=True)

class Workposition(models.Model):
    _name="dtw.workposition"
    _description="工位"
    _order='seq'
    _sql_constraints = [
    ('name_uniq',
    'UNIQUE (name)',
    '工位名称不能重复!')
    ]
    name=fields.Char('工位名称')
    remark=fields.Char('工位说明')
    seq=fields.Integer('工位序号',compute="_compute_name",store=True)
    # company_id = fields.Many2one('res.company', string='Company', default=lambda self: self.env.user.company_id)
    # @api.model_create_multi
    # def create(self, vals_list):
    #     for vals in vals_list:
    #         vals['company_id']=self.env.user.company_id.id    
    #         vals['name'] = vals['name']+'.'+str(vals['company_id'])
    #     return super().create(vals_list)
    @api.depends('name')
    def _compute_name(self):
        for r in self:
            if r.name:
                match=re.search(r'\d+',r.name)
                if match:
                    r.seq=int(match.group())
                else:
                    r.seq=0

class WorkmanshipMain(models.Model):
    _name="dtw.workmanship.main"
    _description="工单"
    _rec_name="name"
    _order="name desc"

    name = fields.Char(
        string="工单号",
        required=True, copy=False, readonly=True,
        index='trigram',
        default=lambda self: _('New'))
    datetime_mainship=fields.Datetime('工单日期',default=fields.Datetime.now())
    remark=fields.Char('说明')
    workmanship_ids=fields.One2many('dtw.workmanship','main_id',string='工单明细')
    company_id = fields.Many2one('res.company',string="组织",default=lambda self: self.env.company.id)
    user_id = fields.Many2one('res.users', default=lambda self: self.env.user.user_id)
    dispatch = fields.Boolean('可下发的工单',default=False)
    dispatched = fields.Boolean('已经下发的工单',default=False)
    state = fields.Selection( [('dispatch','下发'),('to_excel', '下载xlsx文件'),('draft','初稿')], 'State',
                             default='draft')
    no_workmanship=fields.Boolean('无工单明细',compute='_compute_no_workmanship')
    worktype_selection=fields.Selection(selection=WORKTYPE_SELECTION,string='工作模式',default="A1M")
    document_data1 = fields.Binary(string='附件1', attachment=True)
    document_fname1 = fields.Char('附件1名', index=True)
    document_data2 = fields.Binary(string='附件2', attachment=True)
    document_fname2 = fields.Char('附件2名', index=True)
    document_data3 = fields.Binary(string='附件3', attachment=True)
    document_fname3 = fields.Char('附件3名', index=True)
    document_data4 = fields.Binary(string='附件4', attachment=True)
    document_fname4 = fields.Char('附件4名', index=True)
    
    # 工单选择后，更新工单明细。而工单明细的改变不会影响工单的worktype.
    @api.onchange('worktype_selection')
    def _onchange_worktype_selection(self):
        for w in self.workmanship_ids:
            w.worktype_selection=self.worktype_selection

    #多扭矩模式下的工位不能重复
    def write(self,val):
        main_id=self.id
        workmanship_ids=val.get('workmanship_ids',False)
        if workmanship_ids:
            for i in workmanship_ids:
                if i[0]==0:
                    worktype_selection=i[2].get('worktype_selection',False)
                    workposition_id=i[2].get('workposition_id',False)
                    if worktype_selection and worktype_selection=='A1M' or worktype_selection == 'A2M':
                        if self.env['dtw.workmanship'].search([('main_id','=',main_id),('workposition_id','=',workposition_id)]):
                            raise models.ValidationError('多扭矩模式的工位标识不能重复！')
        return super(WorkmanshipMain,self).write(val)            

    @api.depends("workmanship_ids")
    def _compute_no_workmanship(self):
       for r in self:
            r.no_workmanship= not len(r.workmanship_ids)                         
            #根据有没有明细，设置state
            if r.no_workmanship:
                r.state='draft'
            else:
                r.state='dispatch'

    @api.model_create_multi
    def create(self, vals_list):
        for vals in vals_list:
            #处理工位不能有重复项
            workmanship_ids=vals.get('workmanship_ids',False)
            if workmanship_ids:
                position=[]
                for workmanship in workmanship_ids:
                    position.append(workmanship[2]['workposition_id'])
                if len(position) != len(set(position)):
                    raise models.ValidationError('多扭矩模式的工位标识不能重复！')
            vals['company_id']=self.env.company.id    
            self = self.with_company(vals['company_id'])
            if vals.get('name', _("New")) == _("New"):
                # seq_date = fields.Datetime.context_timestamp(
                #     self, fields.Datetime.to_datetime(vals['date_order'])
                # ) if 'date_order' in vals else None
                seq=self.env['ir.sequence'].search([('code','ilike','dtw.workmanship.main'),('company_id','=',vals['company_id'])])
                if not seq:
                    seq=self.env['ir.sequence'].sudo().create({
                        'name':'Workmanship_main',
                        'code':'dtw.workmanship.main.%s' % vals['company_id'],
                        'implementation':'standard',
                        'active':True,
                        'company_id':vals['company_id'],
                        'prefix':'W',
                        'padding':6,
                        'number_increment':1,
                        'suffix':'',
                        'use_date_range':False
                    })
                # vals['name'] = str(vals['company_id'])+'.'+seq.next_by_code('dtw.workmanship.main.%s' % vals['company_id']) or _("New")
                vals['name'] = seq.next_by_code('dtw.workmanship.main.%s' % vals['company_id'])+'.'+ str(vals['company_id']) or _("New")
            # 判断有没有创建明细，设置state    
            if vals.get('workmanship_ids',False):    
                vals['state']='dispatch'    
            else:
                vals['state']='draft'    
        return super().create(vals_list)

    def update_dispatch(self):
        active_list=self.env.context.get('active_ids',self.ids)
        active_model=self.env.context.get('active_model',self._name)
        company_id=self.env.company.id
        #将所有已经下发的部分设置到dispatched,然后还原dispatch=false
        records=self.env[active_model].search([('dispatch','=',True),('company_id','=',company_id)])
        active_records=self.env[active_model].search([('id','in',active_list),('company_id','=',company_id)])
        for r in records:
            r.dispatched=r.dispatch
            for w in r.workmanship_ids:
                w.dispatched=r.dispatch
        # for r in records:
        #     r.dispatch=False
        #     for w in r.workmanship_ids:
        #         w.dispatch=False
        #只设置选中的(原来为false就设置为true,反之亦然)    
        for r in active_records:
            r.dispatch=not r.dispatch
            for w in r.workmanship_ids:
                w.dispatch=r.dispatch  #工单明细跟着工单的设置
            # 对于已经设置过的，又选中的则设置为false.这样可以再选，来取消它 
        #     if r.id in records.ids:
        #         r.dispatch=False
        #         for w in r.workmanship_ids:
        #             w.dispatch=False
        # #只设置选中的    
        #     else:
        #         r.dispatch=True
        #         for w in r.workmanship_ids:
        #             w.dispatch=True
        return

        # backinfo = os.system('ping -c 1 -w 1 %s' % 'www.baidu.co')
        # if backinfo:
        #     self.to_excel()
    def operator_choose(self):
        action = {
                'name': '选择操作员',
                'res_model': 'dtw.operator.wizard',
                'type': 'ir.actions.act_window',
                'view_mode': 'form',
                'views': [[self.env.ref('dtw.operator_choose_wizard_form').id, 'form']],
                'target': 'new',
            }
        return action    

    def to_excel(self):
        action = {
                'name': '导出xlsx',
                'res_model': 'dtw.workmanship',
                'report_type':'xlsx',
                'type': 'ir.actions.report',
                "report_name":"dtw.report_workmanship_xlsx",
                "report_file":"dtw.report_workmanship_xlsx" 
            }
        self.state='dispatch'
        return action

class Workmanship(models.Model):
    _name="dtw.workmanship"
    _description="工单明细"
    _rec_name="name"
    _order="main_id,seq asc"


    name=fields.Char('工艺号',compute="_compute_name")
    main_id=fields.Many2one('dtw.workmanship.main',string='工单号',ondelete="restrict",index=True)
    worktype=fields.Char('模型',compute="_compute_worktype")
    worktype_selection=fields.Selection(selection=WORKTYPE_SELECTION,string='工作模式',default='A1M')
    workposition_id=fields.Many2one('dtw.workposition',string='工位')
    seq=fields.Integer(related='workposition_id.seq',string='工位序号',store=True)
    target_tork=fields.Float(string="扭力",digits='Product Unit of Measure',required="1")
    tork_unit=fields.Selection([('Nm','Nm'),('ft.lb','ft.lb'),('in.lb','in.lb'),('kg.cm','kg.cm')],default="Nm",string='扭力单位',required="1")
    min_tork=fields.Float(string='最小扭力',digits='Product Unit of Measure')
    max_tork=fields.Float(string='最大扭力',digits='Product Unit of Measure')
    allow=fields.Float(string='误差范围:',default=0.05)
    remark=fields.Char("说明")
    angle=fields.Float('角度',digits='Product Unit of Measure',default=0)
    min_angle=fields.Float('最小角度',digits='Product Unit of Measure',default=0)
    max_angle=fields.Float('最大角度',digits='Product Unit of Measure',default=0)
    barcode = fields.Char('二维码',compute="_compute_barcode")
    company_id = fields.Many2one('res.company',string="组织", related="main_id.company_id",store=True)
    # dispatch = fields.Boolean('可下发的工单',related='main_id.dispatch',inverse="_inverse_dispatch")
    dispatch = fields.Boolean('可下发的工单')
    # dispatched = fields.Boolean('已经下发的工单',related='main_id.dispatched',inverse="_inverse_dispatched")
    dispatched = fields.Boolean('已经下发的工单')
    operator_id = fields.Many2one('res.users',string='操作员')

    @api.depends('worktype_selection','seq')
    def _compute_worktype(self):
        for r in self:
            if r.worktype_selection[-1] == '0':
                r.worktype=r.worktype_selection
            else:
                r.worktype=r.worktype_selection + str(r.seq)

    def update_dispatch_workmanship(self):
        active_list=self.env.context.get('active_ids',self.ids)
        active_model=self.env.context.get('active_model',self._name)
        company_id=self.env.company.id
        active_records=self.env[active_model].search([('id','in',active_list),('company_id','=',company_id)])
        for r in active_records:
            r.dispatch=not r.dispatch
        return

    #当选择单扭矩模式则工位设为M0,多扭矩模式工位有M1~M9供选择
    @api.onchange('worktype_selection')
    def _onchange_worktype_selection(self):
        workposition_all=self.env['dtw.workposition'].search([])
        workposition_0=self.env['dtw.workposition'].search([('seq','=',0)])
        workposition_no_0=workposition_all-workposition_0
        if self.worktype_selection=='A1M0' or self.worktype_selection == 'A2M0':
            self.workposition_id=workposition_0.id
        else:
            return {'domain':{'workposition_id':[('id','in',workposition_no_0.ids)]}}
            

    def name_get(self):
        result=[]
        for record in self:
            result.append((record.id, u"%s@%s" % (record.workposition_id.name, record.main_id.name)))
        return result

    @api.depends('main_id','workposition_id')
    def _compute_name(self):
        for r in self:
            r.name="%s@%s" % (r.workposition_id.name,r.main_id.name)    

    @api.depends('target_tork','angle','tork_unit')
    def _compute_barcode(self):
        for r in self:
            # barcode={'worktype_name':r.worktype_id.name,'target_tork':str(r.target_tork),'tork_unit':r.tork_unit,
            #          'min_tork':str(r.min_tork),'max_tork':str(r.max_tork),'angle':str(r.angle),'min_angle':str(r.min_angle),
            #         'max_angle':str(r.max_angle),'workmanship_id':str(r.id)}
            barcode={'worktype':r.worktype,'target_tork':str(r.target_tork),'tork_unit':r.tork_unit,
                     'min_tork':str(r.min_tork),'max_tork':str(r.max_tork),'angle':str(r.angle),'min_angle':str(r.min_angle),
                    'max_angle':str(r.max_angle),'workmanship_id':str(r.id),'main_id':str(r.main_id.id)}
            r.barcode=json.dumps(barcode)                                           
    @api.onchange('target_tork','angle','allow')
    def _onchange_target_tork(self):
        if self.target_tork:
            self.min_tork=self.target_tork*(1-self.allow)
            self.max_tork=self.target_tork*(1+self.allow)
            self.min_angle=self.angle*(1-self.allow)
            self.max_angle=self.angle*(1+self.allow)
    
    @api.constrains("target_tork")
    def _check_torkget_tork(self):
        for r in self:
            if not r.target_tork >0:
                raise models.ValidationError('未设扭矩值！')


class Workdata(models.Model):
    _name="dtw.workdata"
    _description="工作数据"
    _order="datetime_work desc"
    workmanship_id=fields.Many2one('dtw.workmanship',string="工艺号",ondelete="restrict")
    datetime_work=fields.Datetime('操作时间')
    # operator_id=fields.Many2one('dtw.operator',string="操作人员",ondelete="restrict")
    operator_id=fields.Many2one('res.users',string="操作人员",ondelete="restrict",default=lambda self:self.env.uid)
    real_tork=fields.Float(string='实际值')
    real_angle=fields.Float('实际角度值')
    wrench_identity=fields.Char('扳手ID')
    wrench_name=fields.Char('扳手名称')
    main_id=fields.Many2one('dtw.workmanship.main',string="工单号")
    workposition_id=fields.Many2one('dtw.workposition',string='工位')
    target_tork=fields.Float(string="目标扭力值")
    tork_unit=fields.Selection([('Nm','Nm'),('ft.lb','ft.lb'),('in.lb','in.lb'),('kg.cm','kg.cm')],'扭力单位',
                               default='Nm')
    min_tork=fields.Float(string='允许最低值')
    max_tork=fields.Float(string='允许最大值')
    flag=fields.Boolean('超差',default=False,compute='_compute_flag',store=True)
    angle=fields.Float('目标角度值')    
    company_id = fields.Many2one('res.company',string="组织",ondelete="restrict",default=lambda self:self.env.company.id)
    remark=fields.Char("说明")
    worktype=fields.Char("模型")
    @api.model
    def create(self, vals):
        workmanship_id=vals.get('workmanship_id',False)
        # 扳手ID可上传后，即在dtw.wrench_info中存在，则可加上下面    
        wrench_identity=vals.get('wrench_identity',False)
        company_id=vals.get('company_id',False)
        if workmanship_id:
            dtw_workmanship=self.env['dtw.workmanship'].search([('id','=',workmanship_id)])
            vals['main_id']=dtw_workmanship.main_id.id
            vals['workposition_id']=dtw_workmanship.workposition_id.id
            vals['target_tork']=dtw_workmanship.target_tork
            vals['tork_unit']=dtw_workmanship.tork_unit
            vals['min_tork']=dtw_workmanship.min_tork
            vals['max_tork']=dtw_workmanship.max_tork
            vals['angle']=dtw_workmanship.angle
            vals['worktype']=dtw_workmanship.worktype
            # vals['main_id']=self.env['dtw.workmanship'].search([('id','=',workmanship_id)]).main_id.id
            # vals['workposition_id']=self.env['dtw.workmanship'].search([('id','=',workmanship_id)]).workposition_id.id
            # vals['target_tork']=self.env['dtw.workmanship'].search([('id','=',workmanship_id)]).target_tork
            # vals['tork_unit']=self.env['dtw.workmanship'].search([('id','=',workmanship_id)]).tork_unit
            # vals['min_tork']=self.env['dtw.workmanship'].search([('id','=',workmanship_id)]).min_tork
            # vals['max_tork']=self.env['dtw.workmanship'].search([('id','=',workmanship_id)]).max_tork
            # vals['angle']=self.env['dtw.workmanship'].search([('id','=',workmanship_id)]).angle
            # vals['worktype']=self.env['dtw.workmanship'].search([('id','=',workmanship_id)]).worktype
        # 扳手ID可上传后，即在dtw.wrench_info中存在，则可加上下面部分    
        if wrench_identity:
            wrench_info=self.env['dtw.wrench.info'].search([('deviceID','=',wrench_identity),('company_id','=',company_id)])
            if wrench_info:
                wrench_name=self.env['dtw.wrench.info'].search([('deviceID','=',wrench_identity),('company_id','=',company_id)]).name
                vals['wrench_name']=wrench_name    
        #
        return super().create(vals)    

    
    @api.depends('min_tork','max_tork','real_tork')
    def _compute_flag(self):
        for r in self:
            if r.real_tork < r.min_tork or r.real_tork > r.max_tork:
                r.flag=True
            else:
                r.flag=False
    
# class Worktype(models.Model):
#     _name="dtw.worktype"
#     _description="工作模式"
#     _sql_constraints = [
#     ('name_uniq',
#     'UNIQUE (name)',
#     '工作模式不能重复!')
#     ]
#     name=fields.Char('模式名称')
#     remark=fields.Char('模式说明')
#     company_id = fields.Many2one('res.company', string='Company', default=lambda self: self.env.user.company_id)

#     def name_get(self):
#         result=[]
#         for record in self:
#             result.append((record.id, u"%s(%s)" % (record.name, record.remark)))
#         return result

class WrenchInfo(models.Model):
    _name="dtw.wrench.info"
    _description='扳手信息'

    deviceID=fields.Char('扳手ID',readonly=True)
    name=fields.Char('扳手名称')
    company_id = fields.Many2one('res.company', string='组织',readonly=True)
    proto= fields.Selection([('ariter','Ariter'),('bluetork','bluetork')],default='ariter',string="通讯协议")
#     tork_unit=fields.Selection([('Nm','Nm'),('ft.lb','ft.lb'),('in.lb','in.lb'),('kg.cm','kg.cm')],default="Nm",string='扭力单位',required="1")
#     min_tork=fields.Float(string='扭力下限',digits='Product Unit of Measure')
#     max_tork=fields.Float(string='最大上限',digits='Product Unit of Measure')
#     barcode = fields.Char('二维码',compute="_compute_barcode")
#     write_uuid=fields.Char('更新ID')
#     notify_uuid=fields.Char('通知ID')

#     @api.depends('min_tork','max_tork','tork_unit')
#     def _compute_barcode(self):
#         for r in self:
#             barcode={'deviceID':r.deviceID,'name':r.name,'tork_unit':r.tork_unit,
#                      'min_tork':str(r.min_tork),'max_tork':str(r.max_tork)
#                     }
#             r.barcode=json.dumps(barcode)                                           
    def write(self,vals):
        name=vals.get('name',False)
        if name:
            workdata=self.env['dtw.workdata'].search([('wrench_identity','=',self.deviceID)])
            if workdata:
                workdata.wrench_name=name
        return super().write(vals)

    @api.model
    def create(self,vals):
        deviceID=vals.get('deviceID',False)
        if deviceID:
            ids=self.env['dtw.wrench.info'].search([]).mapped('deviceID')
            if deviceID not in ids:
                return super().create(vals)        
        raise ValidationError('设备ID不能重复或空!')         
   
# class Operator(models.Model):
#     _name="dtw.operator"
#     _description="人员信息"
#     user_id=fields.Many2one('res.users',string='odoo用户')
#     name=fields.Char("姓名",related='user_id.partner_id.name',store=True)
#     login=fields.Char('登录名',related='user_id.login',store=True)
#     password=fields.Char('密码')
#     company_id = fields.Many2one('res.company', related='user_id.company_id')
#     mobile=fields.Char('手机',related="user_id.partner_id.mobile",store=True)

#     # 从odoo中获取密码，但是因为加密过了(PBKDF2_SHA-512,https://www.dcode.fr/pbkdf2-hash)
#     # 所以将设置的密码覆盖掉odoo用户的密码
#     @api.model_create_multi
#     def create(self, vals_list):
#         for vals in vals_list:
#             user_id=vals['user_id']
#             self.env['res.users'].browse(user_id).sudo().password=vals['password'] #覆盖odoo用户密码   

#             # cr=self.env.cr    
#             # cr.execute("""
#             # SELECT id, password FROM res_users
#             # WHERE password IS NOT NULL and id=%s
#             # """, (user_id,)) 
#             # if self.env.cr.rowcount:
#             #     pw=cr.fetchall()[0][1]
#             #     if not vals.get('password',False):
#             #         vals['password']= pw
#             #     else:
#             #         self.env['res.users'].browse(user_id).password=vals['password']    
#         return super().create(vals_list)
    
#     def write(self,value):
#         if 'password' in value:
#             self.user_id.sudo().password=value['password'] #覆盖odoo用户密码   
#         return super().write(value)


